package com.skyblue.statemachine.form;

import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.Message;
import org.springframework.statemachine.ExtendedState;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.annotation.*;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
//@WithStateMachine(id = "formMachine")
public class FormEventActionConfig {

    @OnStateMachineStart
    public void OnStateMachineStart(StateMachine<FormStates, FormEvents> stateMachine) {
        log.info("OnStateMachineStart-1 ===>> {}", stateMachine.getState().getId());
    }

    @OnStateMachineStop
    public void OnStateMachineStop(StateMachine<FormStates, FormEvents> stateMachine) {
        log.info("OnStateMachineStop-1 ===>> {}", stateMachine.getState().getId());
    }

    /**
     * 变量值变更监听‌：当调用 StateMachine#setExtendedState() 或通过 ExtendedState#getVariables() 修改数据时触发。
     * ‌跨状态共享数据‌：扩展状态不同于常规状态（State），其生命周期贯穿整个状态机实例，适合存储业务中间数据。
     * ‌条件判断联动‌：与 @OnTransition 配合实现动态路由。
     */
    @OnExtendedStateChanged(key = "header-123")
    public void OnExtendedStateChanged(ExtendedState extendedState) {
        log.info("OnExtendedStateChanged-1 ===>> {}", extendedState.getVariables());
    }

    /**
     * 该标记表示状态机在事件转换过程中拒绝了特定事件，可能由以下原因触发：
     * ‌事件与当前状态不匹配‌：发送的事件未在状态机的当前状态配置中定义有效转换路径
     * ‌条件未满足‌：事件关联的守卫条件（Guard）返回false，阻止状态迁移
     * ‌异步处理冲突‌：并行子状态机之间存在事件竞争或互斥
     */
    @OnEventNotAccepted
    public void OnEventNotAccepted(StateMachine<FormStates, FormEvents> stateMachine, Message<FormEvents> message) {
        log.info("OnEventNotAccepted-1 ===>> {}", stateMachine.getState().getId());
        if (message != null) log.info("OnEventNotAccepted-2 ===>> {}", message.getPayload());
    }

    @OnStateEntry
    public void OnStateEntry(StateMachine<FormStates, FormEvents> stateMachine, Message<FormEvents> message) {
        log.info("OnStateEntry-1 ===>> {}", stateMachine.getState().getId());
        if (message != null) log.info("OnStateEntry-2 ===>> {}", message.getPayload());
    }

    @OnStateEntry
    public void OnStateExit(StateMachine<FormStates, FormEvents> stateMachine, Message<FormEvents> message) {
        log.info("OnStateExit-1 ===>> {}", stateMachine.getState().getId());
        if (message != null) log.info("OnStateExit-2 ===>> {}", message.getPayload());
    }

    // 基础形式：仅获取目标状态
    @OnStateChanged
    public void handleChange(ExtendedState extendedState, StateMachine<FormStates, FormEvents> stateMachine) {
        // state为变更后的新状态
        log.info("handleChange-1：{}, {}", extendedState, stateMachine);
    }

    @OnStateChanged
    public void handleChange(Message<FormEvents> message) {
        // 获取事件关联的元数据
        log.info("handleChange-2 ===>> {}", message);
    }

    // 消息头访问形式：
    @OnStateChanged
    public void handleChange(@EventHeaders Map<String, Object> headers) {
        // 获取事件关联的元数据
        log.info("handleChange-3 ===>> {}", headers);
    }

    /**
     * 当前状态BLANK_FORM
     */
    @OnTransition(target = "BLANK_FORM")
    public void create() {
        log.info("---空白表单---");
    }

    /**
     * BLANK_FORM->FULL_FORM 执行的动作
     */
    @OnTransition(source = "BLANK_FORM", target = "FULL_FORM")
    public void write(Message<FormEvents> message) throws InterruptedException {
        log.info("@OnTransition(source = \"BLANK_FORM\", target = \"FULL_FORM\") ===>> 开始：{}", message.getPayload());
        TimeUnit.MILLISECONDS.sleep(1234);
        log.info("@OnTransition(source = \"BLANK_FORM\", target = \"FULL_FORM\") ===>> 结束：{}", message.getPayload());
    }

    /**
     * FULL_FORM->CONFIRM_FORM 执行的动作
     */
    @OnTransition(source = "FULL_FORM", target = "CONFIRM_FORM")
    public void confirm(Message<FormEvents> message) {
        log.info("---校验表单：{}---", message.getPayload());
    }

    /**
     * CONFIRM_FORM->SUCCESS_FORM 执行的动作
     */
    @OnTransition(source = "CONFIRM_FORM", target = "SUCCESS_FORM")
    public void submit(Message<FormEvents> message) {
        log.info("---表单提交成功：{}---", message.getPayload());
    }

    @OnTransitionStart(source = "CONFIRM_FORM", target = "SUCCESS_FORM")
    public void OnTransitionStart(Message<FormEvents> message) {
        log.info("---OnTransitionStart：{}---", message.getPayload());
    }

    @OnTransitionEnd(source = "CONFIRM_FORM", target = "SUCCESS_FORM")
    public void OnTransitionEnd(Message<FormEvents> message) {
        log.info("---OnTransitionEnd：{}---", message.getPayload());
    }

}
